package com.qumitech.visualnovel.controller.rest.account;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;
import java.util.List;
import java.util.UUID;
import com.qumitech.visualnovel.config.shiro.MyShiroRealm;
import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.model.dao.console.UserInfo;
import com.qumitech.visualnovel.service.account.SysUserRoleService;
import com.qumitech.visualnovel.service.account.UserInfoService;

@RestController
@RequestMapping("/api/userInfo")
public class UserInfoController {
    @Autowired
    UserInfoService userInfoService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @RequestMapping(value = "/userList", method = RequestMethod.GET)
    // @RequiresPermissions("userInfo:view")
    public JSONObject userInfo(
            @RequestParam(value="offset", required = false, defaultValue="0") int offset,
            @RequestParam(value="limit", required=false, defaultValue="20") int pageSize,
            @RequestParam(value="username", required=false) String username,
            @RequestParam(value="startTime", required=false) String startTime,
            @RequestParam(value="endTime", required=false) String endTime,
            @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
            @RequestParam(value="orderBy", required=false, defaultValue="updated_at") String orderBy
            ){
        JSONObject data = new JSONObject();
        int count = userInfoService.getUserInfoCount(username,startTime, endTime);
        data.put("count", count);
        JSONArray dataItems = new JSONArray();
        List<UserInfo> UserInfoList = userInfoService.getUserInfoList(offset,pageSize,username,startTime, endTime,orderBy,orderType);
        for(UserInfo userInfo: UserInfoList)
        {
            dataItems.add(userInfo.toJsonObject());
        }
        data.put("items", dataItems);
        BaseResponse results = new BaseResponse(data);
        return results;
    }

    @RequestMapping(value = "/userAdd", method = RequestMethod.POST)
    public JSONObject userInfoAdd(@RequestBody JSONObject params){
        int roleId = params.getInteger("roleId");
        String password = params.getString("password");
        if (password == null)
        {
            password = UUID.randomUUID().toString().split("-")[0];
        }
        JSONObject data = new JSONObject();
        data.put("password", password);
        BaseResponse results = new BaseResponse(data);
        String userName = params.getString("username");
        try {
            userInfoService.addNewUser(password, userName);
            UserInfo userInfo = userInfoService.getUserByName(userName);
            sysUserRoleService.setUserSysRole(userInfo.getUid(), roleId);
        }catch (DuplicateKeyException e)
        {
            results.put("msg", "用户名已存在");
            results.put("code", -1);
        }
        catch (Exception e)
        {
            results.put("msg", e.toString());
            results.put("code", -1);
        }
        return results;
    }

    @RequestMapping(value = "/userUpdate", method = RequestMethod.POST)
    public JSONObject userInfoUpdate(@RequestBody JSONObject params){
        JSONObject data = new JSONObject();
        BaseResponse results = new BaseResponse(data);
        int uid = params.getInteger("uid");
        int role_id = params.getInteger("roleId");
        try {
            UserInfo userInfo = userInfoService.getUserByUid(Integer.valueOf(uid));
            sysUserRoleService.setUserSysRole(userInfo.getUid(), role_id);

            RealmSecurityManager rsm = (RealmSecurityManager)SecurityUtils.getSecurityManager();
            MyShiroRealm authRealm = (MyShiroRealm)rsm.getRealms().iterator().next();
            authRealm.clearAuthz();

            List<UserInfo> userInfoList = sysUserRoleService.getUsersByRoleId(role_id);
            if(userInfoList != null) {
                Subject subject = SecurityUtils.getSubject();
                UserInfo activeUser = (UserInfo)subject.getPrincipal();
                for (UserInfo curUserInfo : userInfoList){
                    if (activeUser.getUid() == curUserInfo.getUid()) {
                        activeUser.setSysRoleList(curUserInfo.getSysRoleList());
                    }
                }
            }
        }
        catch (Exception e)
        {
            results.put("msg", e.toString());
            results.put("code", -1);
        }
        return results;
    }

    @RequestMapping(value = "/userDel", method = RequestMethod.POST)
    public JSONObject userDel(@RequestBody JSONObject params){
        JSONObject data = new JSONObject();
        int uid = params.getInteger("uid");
        BaseResponse results = new BaseResponse(data);
        try {
            sysUserRoleService.unBindUserSysRole(uid);
            userInfoService.delUserByUid(uid);
        }catch (Exception e)
        {
            results.put("msg", e.toString());
            results.put("code", -1);
        }
        return results;
    }

    @RequestMapping(value = "/resetPassword", method = RequestMethod.GET)
    public JSONObject resetPassword(@RequestParam(value="uid", required = false, defaultValue="0") Integer uid){
        JSONObject data = new JSONObject();
        String password = UUID.randomUUID().toString().split("-")[0];
        data.put("password", password);
        BaseResponse results = new BaseResponse(data);
        try {
            UserInfo userInfo = userInfoService.getUserByUid(uid);
            userInfoService.resetPassword(userInfo, password);
        } catch (Exception e) {
            results.put("msg", e.toString());
            results.put("code", -1);
        }
        return results;
    }

    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    public JSONObject UpdatePassword(@RequestBody JSONObject params){
        JSONObject data = new JSONObject();
        Subject subject = SecurityUtils.getSubject();
        UserInfo activeUser = (UserInfo) subject.getPrincipal();
        String oldPassword = params.getString("oldPassword");
        String newPassword = params.getString("newPassword");
        BaseResponse results = new BaseResponse(data);
        try {
             if (!userInfoService.UpdatePassword(activeUser, oldPassword, newPassword))
             {
                 results.put("msg", "旧密码验证失败");
                 results.put("code", -1);
             }
        } catch (Exception e) {
            results.put("msg", e.toString());
            results.put("code", -1);
        }
        return results;
    }
}

